/***
*
*   Copyright (c) 1999, Valve LLC. All rights reserved.
*
*   This product contains software technology licensed from Id 
*   Software, Inc. ("Id Technology").  Id Technology (c) 1996 Id Software, Inc. 
*   All Rights Reserved.
*
*   This source code contains proprietary and confidential information of
*   Valve LLC and its suppliers.  Access to this code is restricted to
*   persons who have executed a written SDK license with Valve.  Any access,
*   use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef EIFACE_H
#define EIFACE_H

#define INTERFACE_VERSION 140

#include <stdio.h>
#include "archtypes.h"

#define FCVAR_ARCHIVE       (1<<0)  // set to cause it to be saved to vars.rc
#define FCVAR_USERINFO      (1<<1)  // changes the client's info string
#define FCVAR_SERVER        (1<<2)  // notifies players when changed
#define FCVAR_EXTDLL        (1<<3)  // defined by external DLL
#define FCVAR_CLIENTDLL     (1<<4)  // defined by the client dll
#define FCVAR_PROTECTED     (1<<5)  // It's a server cvar, but we don't send the data since it's a password, etc.  Sends 1 if it's not bland/zero, 0 otherwise as value
#define FCVAR_SPONLY        (1<<6)  // This cvar cannot be changed by clients connected to a multiplayer server.
#define FCVAR_PRINTABLEONLY (1<<7)  // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
#define FCVAR_UNLOGGED      (1<<8)  // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log

typedef struct cvar_s
{
    char    *name;
    char    *string;
    int        flags;
    float    value;
    struct cvar_s *next;
} cvar_t;

//
// Defines entity interface between engine and DLLs.
// This header file included by engine files and DLL files.
//
// Before including this header, DLLs must:
//        include progdefs.h
// This is conveniently done for them in extdll.h
//

#ifdef _WIN32
#define DLLEXPORT __stdcall
#else
#define DLLEXPORT /* */
#endif

typedef enum
    {
    at_notice,
    at_console,        // same as at_notice, but forces a ConPrintf, not a message box
    at_aiconsole,    // same as at_console, but only shown if developer level is 2!
    at_warning,
    at_error,
    at_logged        // Server print to console ( only in multiplayer games ).
    } ALERT_TYPE;

// 4-22-98  JOHN: added for use in pfnClientPrintf
typedef enum
    {
    print_console,
    print_center,
    print_chat,
    } PRINT_TYPE;

// For integrity checking of content on clients
typedef enum
{
    force_exactfile,            // File on client must exactly match server's file
    force_model_samebounds,        // For model files only, the geometry must fit in the same bbox
    force_model_specifybounds,    // For model files only, the geometry must fit in the specified bbox
} FORCE_TYPE;

// Returned by TraceLine
typedef struct
    {
    int        fAllSolid;            // if true, plane is not valid
    int        fStartSolid;        // if true, the initial point was in a solid area
    int        fInOpen;
    int        fInWater;
    float    flFraction;            // time completed, 1.0 = didn't hit anything
    vec3_t    vecEndPos;            // final position
    float    flPlaneDist;
    vec3_t    vecPlaneNormal;        // surface normal at impact
    edict_t    *pHit;                // entity the surface is on
    int        iHitgroup;            // 0 == generic, non zero is specific body part
    } TraceResult;

// CD audio status
typedef struct 
{
    int    fPlaying;// is sound playing right now?
    int    fWasPlaying;// if not, CD is paused if WasPlaying is true.
    int    fInitialized;
    int    fEnabled;
    int    fPlayLooping;
    float    cdvolume;
    //BYTE     remap[100];
    int    fCDRom;
    int    fPlayTrack;
} CDStatus;

typedef uint32 CRC32_t;

// Engine hands this to DLLs for functionality callbacks
typedef struct enginefuncs_s
{
   int         (*pfnPrecacheModel)    (char* s);
   int         (*pfnPrecacheSound)    (char* s);
   void        (*pfnSetModel)         (edict_t *e, const char *m);
   int         (*pfnModelIndex)       (const char *m);
   int         (*pfnModelFrames)      (int modelIndex);
   void        (*pfnSetSize)          (edict_t *e, const float *rgflMin, const float *rgflMax);
   void        (*pfnChangeLevel)      (char *s1, char *s2);
   void        (*pfnGetSpawnParms)    (edict_t *ent);
   void        (*pfnSaveSpawnParms)   (edict_t *ent);
   float       (*pfnVecToYaw)         (const float *rgflVector);
   void        (*pfnVecToAngles)      (const float *rgflVectorIn, float *rgflVectorOut);
   void        (*pfnMoveToOrigin)     (edict_t *ent, const float *pflGoal, float dist, int iMoveType);
   void        (*pfnChangeYaw)        (edict_t* ent);
   void        (*pfnChangePitch)      (edict_t* ent);
   edict_t*  (*pfnFindEntityByString) (edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue);
   int         (*pfnGetEntityIllum)   (edict_t* pEnt);
   edict_t*  (*pfnFindEntityInSphere) (edict_t *pEdictStartSearchAfter, const float *org, float rad);
   edict_t*    (*pfnFindClientInPVS)  (edict_t *pEdict);
   edict_t*    (*pfnEntitiesInPVS)    (edict_t *pplayer);
   void        (*pfnMakeVectors)      (const float *rgflVector);
   void        (*pfnAngleVectors)     (const float *rgflVector, float *forward, float *right, float *up);
   edict_t*    (*pfnCreateEntity)     (void);
   void        (*pfnRemoveEntity)     (edict_t* e);
   edict_t*    (*pfnCreateNamedEntity)(int className);
   void        (*pfnMakeStatic)       (edict_t *ent);
   int         (*pfnEntIsOnFloor)     (edict_t *e);
   int         (*pfnDropToFloor)      (edict_t* e);
   int         (*pfnWalkMove)         (edict_t *ent, float yaw, float dist, int iMode);
   void        (*pfnSetOrigin)        (edict_t *e, const float *rgflOrigin);
   void        (*pfnEmitSound)        (edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch);
   void        (*pfnEmitAmbientSound) (edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch);
   void        (*pfnTraceLine)        (const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
   void        (*pfnTraceToss)        (edict_t* pent, edict_t* pentToIgnore, TraceResult *ptr);
   int         (*pfnTraceMonsterHull) (edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
   void        (*pfnTraceHull)        (const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr);
   void        (*pfnTraceModel)       (const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr);
   const char *(*pfnTraceTexture)     (edict_t *pTextureEntity, const float *v1, const float *v2 );
   void        (*pfnTraceSphere)      (const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr);
   void        (*pfnGetAimVector)     (edict_t* ent, float speed, float *rgflReturn);
   void        (*pfnServerCommand)    (char* str);
   void        (*pfnServerExecute)    (void);
   void        (*pfnClientCommand)    (edict_t* pEdict, char* szFmt, ...);
   void        (*pfnParticleEffect)   (const float *org, const float *dir, float color, float count);
   void        (*pfnLightStyle)       (int style, char* val);
   int         (*pfnDecalIndex)       (const char *name);
   int         (*pfnPointContents)    (const float *rgflVector);
   void        (*pfnMessageBegin)     (int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
   void        (*pfnMessageEnd)       (void);
   void        (*pfnWriteByte)        (int iValue);
   void        (*pfnWriteChar)        (int iValue);
   void        (*pfnWriteShort)       (int iValue);
   void        (*pfnWriteLong)        (int iValue);
   void        (*pfnWriteAngle)       (float flValue);
   void        (*pfnWriteCoord)       (float flValue);
   void        (*pfnWriteString)      (const char *sz);
   void        (*pfnWriteEntity)      (int iValue);
   void        (*pfnCVarRegister)     (cvar_t *pCvar);
   float       (*pfnCVarGetFloat)     (const char *szVarName);
   const char* (*pfnCVarGetString)    (const char *szVarName);
   void        (*pfnCVarSetFloat)     (const char *szVarName, float flValue);
   void        (*pfnCVarSetString)    (const char *szVarName, const char *szValue);
   void        (*pfnAlertMessage)     (ALERT_TYPE atype, char *szFmt, ...);
   void        (*pfnEngineFprintf)    (FILE *pfile, char *szFmt, ...);
   void*       (*pfnPvAllocEntPrivateData) (edict_t *pEdict, int32 cb);
   void*       (*pfnPvEntPrivateData)      (edict_t *pEdict);
   void        (*pfnFreeEntPrivateData)    (edict_t *pEdict);
   const char* (*pfnSzFromIndex)      (int iString);
   int         (*pfnAllocString)      (const char *szValue);
   struct entvars_s* (*pfnGetVarsOfEnt)    (edict_t *pEdict);
   edict_t*    (*pfnPEntityOfEntOffset)    (int iEntOffset);
   int         (*pfnEntOffsetOfPEntity)    (const edict_t *pEdict);
   int         (*pfnIndexOfEdict)          (const edict_t *pEdict);
   edict_t*    (*pfnPEntityOfEntIndex)     (int iEntIndex);
   edict_t*    (*pfnFindEntityByVars)      (struct entvars_s* pvars);
   void*       (*pfnGetModelPtr)      (edict_t* pEdict);
   int         (*pfnRegUserMsg)       (const char *pszName, int iSize);
   void        (*pfnAnimationAutomove)     (const edict_t* pEdict, float flTime);
   void        (*pfnGetBonePosition)  (const edict_t* pEdict, int iBone, float *rgflOrigin, float *rgflAngles );
   uint32 (*pfnFunctionFromName)      ( const char *pName );
   const char *(*pfnNameForFunction)  ( uint32 function );
   void        (*pfnClientPrintf)     ( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg ); // JOHN: engine callbacks so game DLL can print messages to individual clients
   void        (*pfnServerPrint)      ( const char *szMsg );
   const char *(*pfnCmd_Args)         ( void );      // these 3 added 
   const char *(*pfnCmd_Argv)         ( int argc );  // so game DLL can easily 
   int         (*pfnCmd_Argc)         ( void );      // access client 'cmd' strings
   void        (*pfnGetAttachment)    (const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles);
   void        (*pfnCRC32_Init)       (CRC32_t *pulCRC);
   void        (*pfnCRC32_ProcessBuffer)   (CRC32_t *pulCRC, void *p, int len);
   void        (*pfnCRC32_ProcessByte)     (CRC32_t *pulCRC, unsigned char ch);
   CRC32_t     (*pfnCRC32_Final)           (CRC32_t pulCRC);
   int32       (*pfnRandomLong)            (int32 lLow,  int32 lHigh);
   float       (*pfnRandomFloat)           (float flLow, float flHigh);
   void        (*pfnSetView)               (const edict_t *pClient, const edict_t *pViewent );
   float       (*pfnTime)             ( void );
   void        (*pfnCrosshairAngle)   (const edict_t *pClient, float pitch, float yaw);
   byte *      (*pfnLoadFileForMe)    (char *filename, int *pLength);
   void        (*pfnFreeFile)         (void *buffer);
   void        (*pfnEndSection)       (const char *pszSectionName); // trigger_endsection
   int         (*pfnCompareFileTime)  (char *filename1, char *filename2, int *iCompare);
   void        (*pfnGetGameDir)       (char *szGetGameDir);
   void        (*pfnCvar_RegisterVariable) (cvar_t *variable);
   void        (*pfnFadeClientVolume) (const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds);
   void        (*pfnSetClientMaxspeed)     (const edict_t *pEdict, float fNewMaxspeed);
   edict_t *   (*pfnCreateFakeClient) (const char *netname); // returns NULL if fake client can't be created
   void        (*pfnRunPlayerMove)    (edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec );
   int         (*pfnNumberOfEntities) (void);
   char*       (*pfnGetInfoKeyBuffer) (edict_t *e); // passing in NULL gets the serverinfo
   char*       (*pfnInfoKeyValue)     (char *infobuffer, char *key);
   void        (*pfnSetKeyValue)      (char *infobuffer, char *key, char *value);
   void        (*pfnSetClientKeyValue)     (int clientIndex, char *infobuffer, char *key, char *value);
   int         (*pfnIsMapValid)       (char *filename);
   void        (*pfnStaticDecal)      ( const float *origin, int decalIndex, int entityIndex, int modelIndex );
   int         (*pfnPrecacheGeneric)  (char* s);
   int         (*pfnGetPlayerUserId)  (edict_t *e ); // returns the server assigned userid for this player.  useful for logging frags, etc.  returns -1 if the edict couldn't be found in the list of clients
   void        (*pfnBuildSoundMsg)    (edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
   int         (*pfnIsDedicatedServer)     (void);// is this a dedicated server?
   cvar_t     *(*pfnCVarGetPointer)   (const char *szVarName);
   unsigned int   (*pfnGetPlayerWONId)     (edict_t *e); // returns the server assigned WONid for this player.  useful for logging frags, etc.  returns -1 if the edict couldn't be found in the list of clients

   // YWB 8/1/99 TFF Physics additions
   void        (*pfnInfo_RemoveKey)   ( char *s, const char *key );
   const char *(*pfnGetPhysicsKeyValue)   ( const edict_t *pClient, const char *key );
   void        (*pfnSetPhysicsKeyValue)   ( const edict_t *pClient, const char *key, const char *value );
   const char *(*pfnGetPhysicsInfoString) ( const edict_t *pClient );
   unsigned short (*pfnPrecacheEvent)     ( int type, const char*psz );
   void           (*pfnPlaybackEvent)     ( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
   unsigned char *(*pfnSetFatPVS)     ( float *org );
   unsigned char *(*pfnSetFatPAS)     ( float *org );
   int         (*pfnCheckVisibility ) ( const edict_t *entity, unsigned char *pset );
   void        (*pfnDeltaSetField)    ( struct delta_s *pFields, const char *fieldname );
   void        (*pfnDeltaUnsetField)  ( struct delta_s *pFields, const char *fieldname );
   void        (*pfnDeltaAddEncoder)  ( char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) );
   int         (*pfnGetCurrentPlayer) ( void );
   int         (*pfnCanSkipPlayer)    ( const edict_t *player );
   int         (*pfnDeltaFindField)   ( struct delta_s *pFields, const char *fieldname );
   void        (*pfnDeltaSetFieldByIndex)  ( struct delta_s *pFields, int fieldNumber );
   void        (*pfnDeltaUnsetFieldByIndex)( struct delta_s *pFields, int fieldNumber );
   void        (*pfnSetGroupMask)     ( int mask, int op );
   int         (*pfnCreateInstancedBaseline) ( int classname, struct entity_state_s *baseline );
   void        (*pfnCvar_DirectSet)   ( struct cvar_s *var, char *value );

   // Forces the client and server to be running with the same version of the specified file
   //  ( e.g., a player model ).
   // Calling this has no effect in single player
   void        (*pfnForceUnmodified)  ( FORCE_TYPE type, float *mins, float *maxs, const char *filename );

   void        (*pfnGetPlayerStats)   ( const edict_t *pClient, int *ping, int *packet_loss );
   void        (*pfnAddServerCommand) ( char *cmd_name, void (*function) (void) );

// Whistler: commented this out to make it compatiable with all versions of HL/CS
// this is just unnecessary for bots
/*
   // For voice communications, set which clients hear eachother.
   // NOTE: these functions take player entity indices (starting at 1).
   qboolean      (*pfnVoice_GetClientListening)(int iReceiver, int iSender);
   qboolean      (*pfnVoice_SetClientListening)(int iReceiver, int iSender, qboolean bListen);

   const char *(*pfnGetPlayerAuthId)   ( edict_t *e );

   struct sequenceEntry_s*  (*pfnSequenceGet) ( const char* fileName, const char* entryName );
   struct sentenceEntry_s*  (*pfnSequencePickSentence)  ( const char* groupName, int pickMethod, int *picked );
   int           (*pfnGetFileSize)           ( char *filename );
   unsigned int  (*pfnGetApproxWavePlayLen)  (const char *filepath);
   int       (*pfnIsCareerMatch)             ( void );
   int       (*pfnGetLocalizedStringLength)  (const char *label);
   void      (*pfnRegisterTutorMessageShown) (int mid);
   int       (*pfnGetTimesTutorMessageShown) (int mid);
   void      (*ProcessTutorMessageDecayBuffer)   (int *buffer, int bufferLength);
   void      (*ConstructTutorMessageDecayBuffer) (int *buffer, int bufferLength);
   void      (*ResetTutorMessageDecayData)   ( void );
*/
} enginefuncs_t;

// Passed to pfnKeyValue
typedef struct KeyValueData_s
{
    char    *szClassName;    // in: entity classname
    char    *szKeyName;        // in: name of key
    char    *szValue;        // in: value of key
    long    fHandled;        // out: DLL sets to true if key-value pair was understood
} KeyValueData;


typedef struct
{
    char        mapName[ 32 ];
    char        landmarkName[ 32 ];
    edict_t    *pentLandmark;
    vec3_t        vecLandmarkOrigin;
} LEVELLIST;
#define MAX_LEVEL_CONNECTIONS    16        // These are encoded in the lower 16bits of ENTITYTABLE->flags

typedef struct 
{
    int            id;                // Ordinal ID of this entity (used for entity <--> pointer conversions)
    edict_t    *pent;            // Pointer to the in-game entity

    int            location;        // Offset from the base data of this entity
    int            size;            // Byte size of this entity's data
    int            flags;            // This could be a short -- bit mask of transitions that this entity is in the PVS of
    string_t    classname;        // entity class name

} ENTITYTABLE;

#define FENTTABLE_PLAYER        0x80000000
#define FENTTABLE_REMOVED        0x40000000
#define FENTTABLE_MOVEABLE        0x20000000
#define FENTTABLE_GLOBAL        0x10000000

typedef struct saverestore_s SAVERESTOREDATA;

#ifdef _WIN32
typedef 
#endif
struct saverestore_s
{
    char        *pBaseData;        // Start of all entity save data
    char        *pCurrentData;    // Current buffer pointer for sequential access
    int            size;            // Current data size
    int            bufferSize;        // Total space for data
    int            tokenSize;        // Size of the linear list of tokens
    int            tokenCount;        // Number of elements in the pTokens table
    char        **pTokens;        // Hash table of entity strings (sparse)
    int            currentIndex;    // Holds a global entity table ID
    int            tableCount;        // Number of elements in the entity table
    int            connectionCount;// Number of elements in the levelList[]
    ENTITYTABLE    *pTable;        // Array of ENTITYTABLE elements (1 for each entity)
    LEVELLIST    levelList[ MAX_LEVEL_CONNECTIONS ];        // List of connections from this level

    // smooth transition
    int            fUseLandmark;
    char        szLandmarkName[20];// landmark we'll spawn near in next level
    vec3_t        vecLandmarkOffset;// for landmark transitions
    float        time;
    char        szCurrentMapName[32];    // To check global entities

} 
#ifdef _WIN32
SAVERESTOREDATA 
#endif
;

typedef enum _fieldtypes
{
    FIELD_FLOAT = 0,        // Any floating point value
    FIELD_STRING,            // A string ID (return from ALLOC_STRING)
    FIELD_ENTITY,            // An entity offset (EOFFSET)
    FIELD_CLASSPTR,            // CBaseEntity *
    FIELD_EHANDLE,            // Entity handle
    FIELD_EVARS,            // EVARS *
    FIELD_EDICT,            // edict_t *, or edict_t *  (same thing)
    FIELD_VECTOR,            // Any vector
    FIELD_POSITION_VECTOR,    // A world coordinate (these are fixed up across level transitions automagically)
    FIELD_POINTER,            // Arbitrary data pointer... to be removed, use an array of FIELD_CHARACTER
    FIELD_INTEGER,            // Any integer or enum
    FIELD_FUNCTION,            // A class function pointer (Think, Use, etc)
    FIELD_BOOLEAN,            // boolean, implemented as an int, I may use this as a hint for compression
    FIELD_SHORT,            // 2 byte integer
    FIELD_CHARACTER,        // a byte
    FIELD_TIME,                // a floating point time (these are fixed up automatically too!)
    FIELD_MODELNAME,        // Engine string that is a model name (needs precache)
    FIELD_SOUNDNAME,        // Engine string that is a sound name (needs precache)

    FIELD_TYPECOUNT,        // MUST BE LAST
} FIELDTYPE;

#ifndef offsetof
#define offsetof(s,m)    (size_t)&(((s *)0)->m)
#endif

#define _FIELD(type,name,fieldtype,count,flags)        { fieldtype, #name, offsetof(type, name), count, flags }
#define DEFINE_FIELD(type,name,fieldtype)            _FIELD(type, name, fieldtype, 1, 0)
#define DEFINE_ARRAY(type,name,fieldtype,count)        _FIELD(type, name, fieldtype, count, 0)
#define DEFINE_ENTITY_FIELD(name,fieldtype)            _FIELD(entvars_t, name, fieldtype, 1, 0 )
#define DEFINE_ENTITY_GLOBAL_FIELD(name,fieldtype)    _FIELD(entvars_t, name, fieldtype, 1, FTYPEDESC_GLOBAL )
#define DEFINE_GLOBAL_FIELD(type,name,fieldtype)    _FIELD(type, name, fieldtype, 1, FTYPEDESC_GLOBAL )

#define FTYPEDESC_GLOBAL            0x0001        // This field is masked for global entity save/restore

typedef struct 
{
   FIELDTYPE        fieldType;
   char            *fieldName;
   int                fieldOffset;
   short            fieldSize;
   short            flags;
} TYPEDESCRIPTION;

#define ARRAYSIZE(p)        (sizeof(p)/sizeof(p[0]))

#include "entity_state.h"

typedef struct customization_s customization_t;

typedef struct 
{
    // Initialize/shutdown the game (one-time call after loading of game .dll )
    void            (*pfnGameInit)            ( void );                
    int             (*pfnSpawn)                ( edict_t *pent );
    void            (*pfnThink)                ( edict_t *pent );
    void            (*pfnUse)                ( edict_t *pentUsed, edict_t *pentOther );
    void            (*pfnTouch)                ( edict_t *pentTouched, edict_t *pentOther );
    void            (*pfnBlocked)            ( edict_t *pentBlocked, edict_t *pentOther );
    void            (*pfnKeyValue)            ( edict_t *pentKeyvalue, KeyValueData *pkvd );
    void            (*pfnSave)                ( edict_t *pent, SAVERESTOREDATA *pSaveData );
    int             (*pfnRestore)            ( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity );
    void            (*pfnSetAbsBox)            ( edict_t *pent );

    void            (*pfnSaveWriteFields)    ( SAVERESTOREDATA *, const char *, void *, TYPEDESCRIPTION *, int );
    void            (*pfnSaveReadFields)    ( SAVERESTOREDATA *, const char *, void *, TYPEDESCRIPTION *, int );

    void            (*pfnSaveGlobalState)        ( SAVERESTOREDATA * );
    void            (*pfnRestoreGlobalState)    ( SAVERESTOREDATA * );
    void            (*pfnResetGlobalState)        ( void );

    qboolean        (*pfnClientConnect)        ( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] );
    
    void            (*pfnClientDisconnect)    ( edict_t *pEntity );
    void            (*pfnClientKill)        ( edict_t *pEntity );
    void            (*pfnClientPutInServer)    ( edict_t *pEntity );
    void            (*pfnClientCommand)        ( edict_t *pEntity );
    void            (*pfnClientUserInfoChanged)( edict_t *pEntity, char *infobuffer );

    void            (*pfnServerActivate)    ( edict_t *pEdictList, int edictCount, int clientMax );
    void            (*pfnServerDeactivate)    ( void );

    void            (*pfnPlayerPreThink)    ( edict_t *pEntity );
    void            (*pfnPlayerPostThink)    ( edict_t *pEntity );

    void            (*pfnStartFrame)        ( void );
    void            (*pfnParmsNewLevel)        ( void );
    void            (*pfnParmsChangeLevel)    ( void );

     // Returns string describing current .dll.  E.g., TeamFotrress 2, Half-Life
    const char     *(*pfnGetGameDescription)( void );     

    // Notify dll about a player customization.
    void            (*pfnPlayerCustomization) ( edict_t *pEntity, struct customization_s *pCustom );  

    // Spectator funcs
    void            (*pfnSpectatorConnect)        ( edict_t *pEntity );
    void            (*pfnSpectatorDisconnect)    ( edict_t *pEntity );
    void            (*pfnSpectatorThink)        ( edict_t *pEntity );

    // Notify game .dll that engine is going to shut down.  Allows mod authors to set a breakpoint.
    void            (*pfnSys_Error)            ( const char *error_string );

    void            (*pfnPM_Move) ( struct playermove_s *ppmove, qboolean server );
    void            (*pfnPM_Init) ( struct playermove_s *ppmove );
    char            (*pfnPM_FindTextureType)( char *name );
    void            (*pfnSetupVisibility)( struct edict_s *pViewEntity, struct edict_s *pClient, unsigned char **pvs, unsigned char **pas );
    void            (*pfnUpdateClientData) ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd );
    int                (*pfnAddToFullPack)( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet );
    void            (*pfnCreateBaseline) ( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs );
    void            (*pfnRegisterEncoders)    ( void );
    int                (*pfnGetWeaponData)        ( struct edict_s *player, struct weapon_data_s *info );

    void            (*pfnCmdStart)            ( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed );
    void            (*pfnCmdEnd)            ( const edict_t *player );

    // Return 1 if the packet is valid.  Set response_buffer_size if you want to send a response packet.  Incoming, it holds the max
    //  size of the response_buffer, so you must zero it out if you choose not to respond.
    int                (*pfnConnectionlessPacket )    ( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size );

    // Enumerates player hulls.  Returns 0 if the hull number doesn't exist, 1 otherwise
    int                (*pfnGetHullBounds)    ( int hullnumber, float *mins, float *maxs );

    // Create baselines for certain "unplaced" items.
    void            (*pfnCreateInstancedBaselines) ( void );

    // One of the pfnForceUnmodified files failed the consistency check for the specified player
    // Return 0 to allow the client to continue, 1 to force immediate disconnection ( with an optional disconnect message of up to 256 characters )
    int                (*pfnInconsistentFile)( const struct edict_s *player, const char *filename, char *disconnect_message );

    // The game .dll should return 1 if lag compensation should be allowed ( could also just set
    //  the sv_unlag cvar.
    // Most games right now should return 0, until client-side weapon prediction code is written
    //  and tested for them.
    int                (*pfnAllowLagCompensation)( void );
} DLL_FUNCTIONS;

extern DLL_FUNCTIONS        gEntityInterface;

// Current version.
#define NEW_DLL_FUNCTIONS_VERSION    1

typedef struct
{
    // Called right before the object's memory is freed. 
    // Calls its destructor.
    void            (*pfnOnFreeEntPrivateData)(edict_t *pEnt);
    void            (*pfnGameShutdown)(void);
    int                (*pfnShouldCollide)( edict_t *pentTouched, edict_t *pentOther );
} NEW_DLL_FUNCTIONS;
typedef int    (*NEW_DLL_FUNCTIONS_FN)( NEW_DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion );

// Pointers will be null if the game DLL doesn't support this API.
extern NEW_DLL_FUNCTIONS    gNewDLLFunctions;

typedef int    (*APIFUNCTION)( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion );
typedef int    (*APIFUNCTION2)( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion );

#endif EIFACE_H

